import React from 'react'
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types'
import RcTable, { INTERNAL_COL_DEFINE } from 'rc-table'
import classNames from 'classnames';
import shallowEqual from 'shallowequal';
import { Button, Icon } from 'antd';
import Spin from '@/components/Spin'
import SelectionBox from '@/components/SelectionBox';
import Pagination from '../Pagination'
import createStore from 'antd/es/table/createStore'
import createBodyRow from 'antd/es/table/createBodyRow';
import SelectionCheckboxAll from './SelectionCheckboxAll';
import { flatArray, treeMap, flatFilter, normalizeColumns } from 'antd/es/table/util'

function noop() {}
function stopPropagation(e) {
	e.stopPropagation();
	if (e.nativeEvent.stopImmediatePropagation) {
		e.nativeEvent.stopImmediatePropagation();
	}
}
function getRowSelection(props) {
  return props.rowSelection || {};
}
const defaultPagination = {
  onChange: noop,
  onShowSizeChange: noop,
}
const emptyObject = {}

export default class Table extends React.Component {
	constructor(props) {
		super(props)
		this.columns = props.columns || normalizeColumns(props.children)

		this.createComponents(props.components);

		this.state = {
			...this.getDefaultSortOrder(this.columns),
	      	pagination: this.getDefaultPagination(props),
	    }
		this.CheckboxPropsCache = {};

		this.store = createStore({
			selectedRowKeys: getRowSelection(props).selectedRowKeys || [],
			selectionDirty: false,
		});
	}
	static propTypes = {
		columns: PropTypes.array,
		data: PropTypes.array
	};
	static defaultProps = {
		rowKey: 'id',
		useFixedHeader: true,
		data: [],
		loading: false,
		scroll: {
			x: true,
			y: true
		},
		sortDirections: ['asc', 'desc']
	};
	hasPagination(props) {
		return (props || this.props).pagination !== false;
	}
	getSortOrderColumns(columns) {
		return flatFilter(
			columns || this.columns || [],
			(column) => 'sortOrder' in column,
		);
	}
	getLocalData(state) {
		// const currentState = state || this.state
    	const { data } = this.props
    	let _data = data || []
    	_data = _data.slice(0)
    	return _data
	}
	getDefaultPagination(props) {
		const pagination =
			typeof props.pagination === 'object' ? props.pagination : {};
		let pageNumber;
		if ('pageNumber' in pagination) {
			pageNumber = pagination.pageNumber;
		} else if ('defaultCurrent' in pagination) {
			pageNumber = pagination.defaultCurrent;
		}
		let pageSize;
		if ('pageSize' in pagination) {
			pageSize = pagination.pageSize;
		} else if ('defaultPageSize' in pagination) {
			pageSize = pagination.defaultPageSize;
		}
		return this.hasPagination(props) ?
			{
				...defaultPagination,
				...pagination,
				pageNumber: pageNumber || 1,
				pageSize: pageSize || 20,
			} :
			{};
	}
	getDefaultSelection() {
		const rowSelection = getRowSelection(this.props);
		if (!rowSelection.getCheckboxProps) {
			return [];
		}
		return this.getFlatData()
			.filter((item, rowIndex) => this.getCheckboxPropsByItem(item, rowIndex).defaultChecked)
			.map((record, rowIndex) => this.getRecordKey(record, rowIndex));
	}
	componentWillReceiveProps(nextProps) {
		this.columns = nextProps.columns || normalizeColumns(nextProps.children);
		if ('pagination' in nextProps || 'pagination' in this.props) {
			this.setState(previousState => {
				const newPagination = {
					...defaultPagination,
					...previousState.pagination,
					...nextProps.pagination,
				};
				newPagination.pageNumber = newPagination.pageNumber || 1;
				newPagination.pageSize = newPagination.pageSize || 10;
				return {
					pagination: nextProps.pagination !== false ? newPagination : emptyObject
				};
			});
		}
		if (nextProps.rowSelection && 'selectedRowKeys' in nextProps.rowSelection) {
			this.store.setState({
				selectedRowKeys: nextProps.rowSelection.selectedRowKeys || [],
			});
		} else if (this.props.rowSelection && !nextProps.rowSelection) {
			this.store.setState({
				selectedRowKeys: [],
			});
		}
		if ('data' in nextProps && nextProps.data !== this.props.data) {
			this.store.setState({
				selectionDirty: false,
			});
		}

		this.CheckboxPropsCache = {};

		if (this.getSortOrderColumns(this.columns).length > 0) {
			const sortState = this.getSortStateFromColumns(this.columns);
			if (
				sortState.sortColumn !== this.state.sortColumn ||
				sortState.sortOrder !== this.state.sortOrder
			) {
				this.setState(sortState);
			}
		}

		this.createComponents(nextProps.components, this.props.components);
	}
	onRow = (prefixCls, record, index) => {
		const {
			rowSelection
		} = this.props
		const rowKey = this.getRecordKey(record, index)
		const {
			onRow = (item, i) => {
				return {
					onClick: event => {
						if (rowSelection && !this.getCheckboxPropsByItem(item, i).disabled) {
							const state = this.store.getState()
							const defaultSelection = state.selectionDirty ? [] : this.getDefaultSelection();
							let selectedRowKeys = state.selectedRowKeys.concat(defaultSelection);
							
							let checked
							if (selectedRowKeys.indexOf(rowKey) === -1) {
								// selectedRowKeys.push(rowKey);
								selectedRowKeys = [rowKey];
								this.setState({
									pivot: i
								});
								checked = true
							} else {
								// selectedRowKeys = selectedRowKeys.filter((i) => rowKey !== i);
								if (selectedRowKeys.length > 1) {
									selectedRowKeys = [rowKey]
									checked = true
								} else {
								 	selectedRowKeys = [];
									checked = false
								}
							}

							this.store.setState({
								selectionDirty: true,
							});
							this.setSelectedRowKeys(selectedRowKeys, {
								selectWay: 'onSelect',
								record: item,
								checked,
								changeRowKeys: void 0,
								nativeEvent: event.nativeEvent,
							});
						}
					}
				}
			}
		} = this.props;
		const custom = onRow(record, index)
		return {
			...custom,
			prefixCls,
			store: this.store,
			rowKey: rowKey,
		};
	};
	setSelectedRowKeys(selectedRowKeys, selectionInfo) {
		const {
			selectWay,
			record,
			checked,
			changeRowKeys,
			nativeEvent
		} = selectionInfo;
		const rowSelection = getRowSelection(this.props);
		if (rowSelection && !('selectedRowKeys' in rowSelection)) {
			this.store.setState({
				selectedRowKeys
			});
		}
		const data = this.getFlatData();
		if (!rowSelection.onChange && !rowSelection[selectWay]) {
			return;
		}
		const selectedRows = data.filter(
			(row, i) => selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0,
		);
		if (rowSelection.onChange) {
			rowSelection.onChange(selectedRowKeys, selectedRows);
		}
		if (selectWay === 'onSelect' && rowSelection.onSelect) {
			rowSelection.onSelect(record, checked, selectedRows, nativeEvent);
		} else if (selectWay === 'onSelectMultiple' && rowSelection.onSelectMultiple) {
			const changeRows = data.filter(
				(row, i) => changeRowKeys.indexOf(this.getRecordKey(row, i)) >= 0,
			);
			rowSelection.onSelectMultiple(checked, selectedRows, changeRows);
		} else if (selectWay === 'onSelectAll' && rowSelection.onSelectAll) {
			const changeRows = data.filter(
				(row, i) => changeRowKeys.indexOf(this.getRecordKey(row, i)) >= 0,
			);
			rowSelection.onSelectAll(checked, selectedRows, changeRows);
		} else if (selectWay === 'onSelectInvert' && rowSelection.onSelectInvert) {
			rowSelection.onSelectInvert(selectedRowKeys);
		}
	}
	renderPagination(prefixCls) {
		if (!this.hasPagination()) {
	      return null;
	    }
	    const { pagination } = this.state;
	    const total = pagination.total || this.getLocalData().length;
		const pageCls = `${prefixCls}-footer`
		return (
			<div className={pageCls}>
				<Pagination 
				showTotal={(total, range, pageNumber, pageSize, pages) => `共${pages}页，每页${pageSize}条，当前第${pageNumber}/${pages}页，共${total}条`}
				{...pagination}
				onChange={this.handlePageChange}
				total={total} 
				pageNumber={this.getMaxCurrent(total)} />
			</div>
		)
	}
	getColumnKey(column, index) {
		return column.key || column.dataIndex || index;
	}
	getMaxCurrent(total) {
		const {
			pagination: {
				pageNumber,
				pageSize
			}
		} = this.state;
		if ((pageNumber - 1) * pageSize >= total) {
			return Math.floor((total - 1) / pageSize) + 1;
		}
		return pageNumber;
	}
	prepareParamsArguments(state) {
		const pagination = { ...state.pagination };
		delete pagination.onChange;
		delete pagination.onShowSizeChange;
		const sorter = {};
		if (state.sortColumn && state.sortOrder) {
			sorter.column = state.sortColumn;
			sorter.order = state.sortOrder;
			sorter.field = state.sortColumn.dataIndex;
			sorter.columnKey = this.getColumnKey(state.sortColumn);
		}

		const extra = {
			data: this.getLocalData(state),
		};

		return [pagination, sorter, extra];
	}
	getCurrentPageData() {
		let data = this.getLocalData();
		let pageNumber;
		let pageSize;
		const state = this.state;
		if (!this.hasPagination()) {
			pageSize = Number.MAX_VALUE;
			pageNumber = 1;
		} else {
			pageSize = state.pagination.pageSize;
			pageNumber = this.getMaxCurrent(state.pagination.total || data.length);
		}

		if (data.length > pageSize || pageSize === Number.MAX_VALUE) {
			data = data.filter((_, i) => {
				return i >= (pageNumber - 1) * pageSize && i < pageNumber * pageSize;
			});
		}
		return data
	}
	getFlatData() {
		const {
			childrenColumnName
		} = this.props;
		return flatArray(this.getLocalData(null, false), childrenColumnName);
	}
	getFlatCurrentPageData() {
		const {
			childrenColumnName
		} = this.props;
		return flatArray(this.getCurrentPageData(), childrenColumnName);
	}
	getDefaultSortOrder(columns) {
		const definedSortState = this.getSortStateFromColumns(columns);

		const defaultSortedColumn = flatFilter(
			columns || [],
			column => column.defaultSortOrder != null,
		)[0];

		if (defaultSortedColumn && !definedSortState.sortColumn) {
			return {
				sortColumn: defaultSortedColumn,
				sortOrder: defaultSortedColumn.defaultSortOrder,
			};
		}
		return definedSortState;
	}
	getSortStateFromColumns(columns) {
		const sortedColumn = this.getSortOrderColumns(columns).filter(
			col => col.sortOrder,
		)[0];

		if (sortedColumn) {
			return {
				sortColumn: sortedColumn,
				sortOrder: sortedColumn.sortOrder,
			};
		}

		return {
			sortColumn: null,
			sortOrder: null,
		};
	}
	getSorterFn(state) {
		const {
			sortOrder,
			sortColumn
		} = state || this.state;
		if (!sortOrder || !sortColumn || typeof sortColumn.sorter !== 'function') {
			return;
		}

		return (a, b) => {
			const result = (sortColumn.sorter)(a, b, sortOrder);
			if (result !== 0) {
				return sortOrder === 'desc' ? -result : result;
			}
			return 0;
		};
	}
	isSameColumn(a, b) {
		if (a && b && a.key && a.key === b.key) {
			return true;
		}
		return (
			a === b ||
			shallowEqual(a, b, (value, other) => {
				if (typeof value === 'function' && typeof other === 'function') {
					return value === other || value.toString() === other.toString();
				}
			})
		);
	}
	toggleSortOrder(column) {
		if (!column.sorter) {
			return;
		}
		const sortDirections = column.sortDirections || this.props.sortDirections
		const {
			sortOrder,
			sortColumn
		} = this.state;
		let newSortOrder
		if (this.isSameColumn(sortColumn, column) && sortOrder !== undefined) {
			const methodIndex = sortDirections.indexOf(sortOrder) + 1;
			newSortOrder =
				methodIndex === sortDirections.length ? undefined : sortDirections[methodIndex];
		} else {
			newSortOrder = sortDirections[0];
		}

		const newState = {
			sortOrder: newSortOrder,
			sortColumn: newSortOrder ? column : null,
		};

		if (this.getSortOrderColumns().length === 0) {
			this.setState(newState);
		}

		const {
			onChange
		} = this.props;
		if (onChange) {
			onChange.apply(
				null,
				this.prepareParamsArguments({
					...this.state,
					...newState,
				}),
			);
		}
	}
	handleSelect = (record, rowIndex, e) => {
		const checked = e.target.checked;
		const nativeEvent = e.nativeEvent;
		const defaultSelection = this.store.getState().selectionDirty ? [] : this.getDefaultSelection();
		let selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection);
		const key = this.getRecordKey(record, rowIndex);
		const {
			pivot
		} = this.state;
		const rows = this.getFlatCurrentPageData();
		let realIndex = rowIndex;
		if (this.props.expandedRowRender) {
			realIndex = rows.findIndex(row => this.getRecordKey(row, rowIndex) === key);
		}

		if (nativeEvent.shiftKey && pivot !== undefined && realIndex !== pivot) {
			const changeRowKeys = [];
			const direction = Math.sign(pivot - realIndex);
			const dist = Math.abs(pivot - realIndex);
			let step = 0;
			while (step <= dist) {
				const i = realIndex + step * direction;
				step += 1;
				const row = rows[i];
				const rowKey = this.getRecordKey(row, i);
				const checkboxProps = this.getCheckboxPropsByItem(row, i);
				if (!checkboxProps.disabled) {
					if (selectedRowKeys.includes(rowKey)) {
						if (!checked) {
							selectedRowKeys = selectedRowKeys.filter((j) => rowKey !== j);
							changeRowKeys.push(rowKey);
						}
					} else if (checked) {
						selectedRowKeys.push(rowKey);
						changeRowKeys.push(rowKey);
					}
				}
			}

			this.setState({
				pivot: realIndex
			});
			this.store.setState({
				selectionDirty: true,
			});
			this.setSelectedRowKeys(selectedRowKeys, {
				selectWay: 'onSelectMultiple',
				record,
				checked,
				changeRowKeys,
				nativeEvent,
			});
		} else {
			if (checked) {
				selectedRowKeys.push(this.getRecordKey(record, realIndex));
			} else {
				selectedRowKeys = selectedRowKeys.filter((i) => key !== i);
			}

			this.setState({
				pivot: realIndex
			});
			this.store.setState({
				selectionDirty: true,
			});
			this.setSelectedRowKeys(selectedRowKeys, {
				selectWay: 'onSelect',
				record,
				checked,
				changeRowKeys: void 0,
				nativeEvent,
			});
		}
	};
	handleRadioSelect = (record, rowIndex, e) => {
		const checked = e.target.checked;
		const nativeEvent = e.nativeEvent;
		const key = this.getRecordKey(record, rowIndex);
		const selectedRowKeys = [key];
		this.store.setState({
			selectionDirty: true,
		});
		this.setSelectedRowKeys(selectedRowKeys, {
			selectWay: 'onSelect',
			record,
			checked,
			changeRowKeys: void 0,
			nativeEvent,
		});
	};
	handleSelectRow = (selectionKey, index, onSelectFunc) => {
		const data = this.getFlatCurrentPageData();
		const defaultSelection = this.store.getState().selectionDirty ? [] : this.getDefaultSelection();
		const selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection);
		const changeableRowKeys = data
			.filter((item, i) => !this.getCheckboxPropsByItem(item, i).disabled)
			.map((item, i) => this.getRecordKey(item, i));

		const changeRowKeys = [];
		let selectWay = 'onSelectAll';
		let checked;
		switch (selectionKey) {
			case 'all':
				changeableRowKeys.forEach(key => {
					if (selectedRowKeys.indexOf(key) < 0) {
						selectedRowKeys.push(key);
						changeRowKeys.push(key);
					}
				});
				selectWay = 'onSelectAll';
				checked = true;
				break;
			case 'removeAll':
				changeableRowKeys.forEach(key => {
					if (selectedRowKeys.indexOf(key) >= 0) {
						selectedRowKeys.splice(selectedRowKeys.indexOf(key), 1);
						changeRowKeys.push(key);
					}
				});
				selectWay = 'onSelectAll';
				checked = false;
				break;
			case 'invert':
				changeableRowKeys.forEach(key => {
					if (selectedRowKeys.indexOf(key) < 0) {
						selectedRowKeys.push(key);
					} else {
						selectedRowKeys.splice(selectedRowKeys.indexOf(key), 1);
					}
					changeRowKeys.push(key);
					selectWay = 'onSelectInvert';
				});
				break;
			default:
				break;
		}

		this.store.setState({
			selectionDirty: true,
		});
		const {
			rowSelection
		} = this.props;
		let customSelectionStartIndex = 2;
		if (rowSelection && rowSelection.hideDefaultSelections) {
			customSelectionStartIndex = 0;
		}
		if (index >= customSelectionStartIndex && typeof onSelectFunc === 'function') {
			return onSelectFunc(changeableRowKeys);
		}
		this.setSelectedRowKeys(selectedRowKeys, {
			selectWay,
			checked,
			changeRowKeys,
		});
	};
	handlePageChange = (pageNumber, ...otherArguments) => {
		const props = this.props;
		const pagination = { ...this.state.pagination };
		if (pageNumber) {
			pagination.pageNumber = pageNumber;
		} else {
			pagination.pageNumber = pagination.pageNumber || 1;
		}
		pagination.onChange(pagination.pageNumber, ...otherArguments);

		const newState = {
			pagination,
		};
		if (props.pagination && typeof props.pagination === 'object' && 'pageNumber' in props.pagination) {
			newState.pagination = {
				...pagination,
				pageNumber: this.state.pagination.pageNumber,
			};
		}
		this.setState(newState);

		this.store.setState({
			selectionDirty: false,
		});

		const {
			onChange
		} = this.props;
		if (onChange) {
			onChange.apply(
				null,
				this.prepareParamsArguments({
					...this.state,
					selectionDirty: false,
					pagination,
				}),
			);
		}
	};
	getRecordKey = (record, index) => {
		const {
			rowKey
		} = this.props;
		const recordKey =
			typeof rowKey === 'function' ? rowKey(record, index) : record[rowKey];

		return recordKey === undefined ? index : recordKey;
	};
	getPopupContainer = () => {
		return ReactDOM.findDOMNode(this);
	};
	generatePopupContainerFunc = () => {
		const {
			scroll
		} = this.props;

		return scroll ? this.getPopupContainer : undefined;
	};
	getCheckboxPropsByItem = (item, index) => {
		const rowSelection = getRowSelection(this.props);
		if (!rowSelection.getCheckboxProps) {
			return {};
		}
		const key = this.getRecordKey(item, index);
		if (!this.CheckboxPropsCache[key]) {
			this.CheckboxPropsCache[key] = rowSelection.getCheckboxProps(item)
		}
		return this.CheckboxPropsCache[key];
	};
	renderSelectionBox = (type) => {
		return (_, record, index) => {
			const rowKey = this.getRecordKey(record, index);
			const props = this.getCheckboxPropsByItem(record, index);
			const handleChange = (e) => {
				type === 'radio' ?
					this.handleRadioSelect(record, index, e) :
					this.handleSelect(record, index, e);
			};

			return (
				<span onClick={stopPropagation}>
		          <SelectionBox
		            type={type}
		            store={this.store}
		            rowIndex={rowKey}
		            onChange={handleChange}
		            defaultSelection={this.getDefaultSelection()}
		            {...props}
		            prefixCls="x-selectable"
		          />
		        </span>
			);
		};
	};
	renderRowSelection(prefixCls) {
		const {
			rowSelection
		} = this.props
		const columns = this.columns.concat()
		if (rowSelection) {
			const data = this.getFlatCurrentPageData().filter((item, index) => {
				if (rowSelection.getCheckboxProps) {
					return !this.getCheckboxPropsByItem(item, index).disabled;
				}
				return true;
			});
			const selectionColumnClass = classNames(`${prefixCls}-selection-column`, {
				[`${prefixCls}-selection-column-custom`]: rowSelection.selections,
			});
			const selectionColumn = {
				key: 'selection-column',
				render: this.renderSelectionBox(rowSelection.type),
				className: selectionColumnClass,
				fixed: rowSelection.fixed,
				width: rowSelection.columnWidth,
				title: rowSelection.columnTitle,
				[INTERNAL_COL_DEFINE]: {
		          	className: `${prefixCls}-selection-col`,
		        }
			}
			if (rowSelection.type !== 'radio') {
				const checkboxAllDisabled = data.every(
					(item, index) => this.getCheckboxPropsByItem(item, index).disabled,
				);
				selectionColumn.title = selectionColumn.title || (
					<SelectionCheckboxAll
			            store={this.store}
			            data={data}
			            locale={{
			            	selectAll: '全选当页',
    						selectInvert: '反选当页'
			            }}
			            getCheckboxPropsByItem={this.getCheckboxPropsByItem}
			            getRecordKey={this.getRecordKey}
			            disabled={checkboxAllDisabled}
			            prefixCls={prefixCls}
			            onSelect={this.handleSelectRow}
			            selections={rowSelection.selections}
			            hideDefaultSelections={rowSelection.hideDefaultSelections}
			            getPopupContainer={this.generatePopupContainerFunc()}
			          />
				);
			}
			if ('fixed' in rowSelection) {
				selectionColumn.fixed = rowSelection.fixed;
			} else if (columns.some(column => column.fixed === 'left' || column.fixed === true)) {
				selectionColumn.fixed = 'left';
			}
			if (columns[0] && columns[0].key === 'selection-column') {
				columns[0] = selectionColumn;
			} else {
				columns.unshift(selectionColumn);
			}
		}
		return columns
	}
	createComponents(components = {}, prevComponents) {
		const bodyRow = components && components.body && components.body.row;
		const preBodyRow = prevComponents && prevComponents.body && prevComponents.body.row;
		if (!this.row || bodyRow !== preBodyRow) {
			this.row = createBodyRow(bodyRow);
		}
		this.components = {
			...components,
			body: {
				...components.body,
				row: this.row,
			},
		};
	}
	renderColumnTitle(title) {
	    const { sortOrder } = this.state;
	    if (title instanceof Function) {
	      return title({
	        sortOrder,
	      });
	    }
	    return title;
	}
	isSortColumn(column) {
		const {
			sortColumn
		} = this.state;
		if (!column || !sortColumn) {
			return false;
		}
		return this.getColumnKey(sortColumn) === this.getColumnKey(column);
	}
	renderColumnsDropdown(
		prefixCls,
		columns
	) {
		const {
			sortOrder
		} = this.state;
		return treeMap(columns, (column, i) => {
			// const key = this.getColumnKey(column, i)
			let sortButton;
			let onHeaderCell = column.onHeaderCell;
			const isSortColumn = this.isSortColumn(column);
			
			if (column.sorter) {
				const sortDirections = column.sortDirections || this.props.sortDirections;
				const isAscend = isSortColumn && sortOrder === 'asc';
				const isDescend = isSortColumn && sortOrder === 'desc';

				const ascend = sortDirections.indexOf('asc') !== -1 && (
					<Icon
			            className={`${prefixCls}-column-sorter-up ${isAscend ? 'on' : 'off'}`}
			            type="caret-up"
			            theme="filled"
			          />
				);
				const descend = sortDirections.indexOf('desc') !== -1 && (
					<Icon
			            className={`${prefixCls}-column-sorter-down ${isDescend ? 'on' : 'off'}`}
			            type="caret-down"
			            theme="filled"
			          />
				);
				sortButton = (
					<div
			            title="排序"
			            className={classNames(
			              `${prefixCls}-column-sorter-inner`,
			              ascend && descend && `${prefixCls}-column-sorter-inner-full`,
			            )}
			            key="sorter"
			          >
			            {ascend}
			            {descend}
			          </div>
				);
				onHeaderCell = col => {
					let colProps = {};
					if (column.onHeaderCell) {
						colProps = {
							...column.onHeaderCell(col),
						};
					}
					const onHeaderCellClick = colProps.onClick;
					colProps.onClick = (...args) => {
						this.toggleSortOrder(column);
						if (onHeaderCellClick) {
							onHeaderCellClick(...args);
						}
					};
					return colProps;
				};
			}
			return {
				...column,
				className: classNames(column.className, {
					[`${prefixCls}-column-has-actions`]: sortButton,
					[`${prefixCls}-column-has-sorters`]: sortButton,
					[`${prefixCls}-column-sort`]: isSortColumn && sortOrder,
				}),
				title: [
					<span key="title" className={`${prefixCls}-header-column`}>
			            <div className={sortButton ? `${prefixCls}-column-sorters` : undefined}>
			              <span className={`${prefixCls}-column-title`}>
			                {this.renderColumnTitle(column.title)}
			              </span>
			              <span className={`${prefixCls}-column-sorter`}>{sortButton}</span>
			            </div>
			        </span>
				],
				onHeaderCell,
			};
		});
	}
	renderTable(prefixCls) {
		const { forceFit, ...props } = this.props;
		let data = this.getCurrentPageData()
		let columns = this.renderRowSelection(prefixCls);
		columns = this.renderColumnsDropdown(prefixCls, columns);
		columns = columns.map((column, i) => {
			const newColumn = { ...column
			};
			newColumn.key = this.getColumnKey(newColumn, i);
			return newColumn;
		});
		if (forceFit === false) {
			const forceColumn = {
				key: 'force-column'
			}
			columns.push(forceColumn)
		}
		return (
			<RcTable 
				{...props} 
				data={data}
	        	columns={columns}
				prefixCls={prefixCls}
				onRow={(record, index) => this.onRow(prefixCls, record, index)}
        		components={this.components} />
		)
	}
	renderComponent(prefixCls) {
		let { showHeader, showReload, loading } = this.props
		if (typeof loading === 'boolean') {
			loading = {
				spinning: loading
			}
		}
		const table = (
			this.renderTable(prefixCls)
		)
		return (
			<Spin
	        	{...loading}
	        >
	          {showHeader !== false && showReload !== false && (<Button type="link" className={`${prefixCls}-reload`} size="small" disabled={this.props.loading} icon="reload" onClick={this.props.onReload}></Button>)}
	          {table}
	          {this.renderPagination(prefixCls)}
	        </Spin>
		)
	}
	render() {
		const { prefixCls } = this.props
		
		return (
			<>
				{this.renderComponent(prefixCls)}
			</>
		)
	}
}